//  Copyright 2011 Charlie Garrett
//
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at
//
//  http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//
//  Parser.h
//

#ifndef PARSER_H
#define PARSER_H

#include <istream>

#include "Lexeme.h"
#include "Term.h"

namespace logic {
    
    // A Parser reads a program from an input stream.  The Parser holds a reference
    // to the input stream, which should not be destroyed before the Parser.
    class Parser {
    public:
        Parser(istream &in, bool tr = false);
        
        Program *ParseProgram();
        Predicate *ParseQuery();
        
    private:
        istream &input;
        Lexeme<istream::char_type> cur_token;
        map<string, Variable*> variables;      // Within a clause or query, variables are unique.
        bool trace;
        
        bool ConsumeToken();
        bool ConsumeTokenOfKind(LexemeKind kind);
        
        bool AtEOF();
        bool InputValid();
        
        void Trace(const char *function);
        void Trace(const char *function, const LexemeKind kind);
    
        Clause *ParseClause();
        Predicate *ParseLiteral();
        vector<Term*> *ParseParameters();
        vector<Term*> *ParseArguments();
        Term *ParseTerm();
        Term *ParseNumericTerm(bool have_minus);
        Term *ParseSymbolicTerm(bool have_minus);
        string ParseOperation();
        vector<Predicate*> *ParseClauseTail();
        vector<Predicate*> *ParseLiterals();
        Term *ParseList();
        Term *ParseListArgs();
        vector<Term*> *ParseListArgsEnd();
    };
}  // namespace logic

#endif  // PARSER_H
